import os
import sys
import time
import datetime
import warnings

import pandas as pd
from dateutil.tz import *
from joblib import Parallel, delayed
from tools.logger import logger
sys.path.append('..')
warnings.filterwarnings('ignore')

from tools.setting import DATA_DIR
from API.binance import fetch_binance_exchangeinfo, fetch_binance_funding_rate
FUNDING_RATE_DATA_DIR = os.path.join(DATA_DIR, 'funding_rate')
os.makedirs(FUNDING_RATE_DATA_DIR, exist_ok=True)


def update_all_binance_funding_rate():
    # 更新币安所有合约的资金费率
    logger.info('更新币安的资金费率')
    file_path = os.path.join(FUNDING_RATE_DATA_DIR, r'all_market_funding_rate')
    os.makedirs(file_path, exist_ok=True)

    end_date = datetime.datetime.today().strftime('%Y-%m-%d')
    timezone = '+0000'

    data_cm = fetch_binance_exchangeinfo(type='cm_futures', trading=False)
    data_cm = data_cm[data_cm['contractType'] == 'PERPETUAL']
    cm_symbol_list = list(data_cm['symbol'])
    data_um = fetch_binance_exchangeinfo(type='um_futures', trading=False)
    data_um = data_um[data_um['contractType'] == 'PERPETUAL']
    um_symbol_list = list(data_um['symbol'])

    symbol_list = []
    symbol_list.extend(cm_symbol_list)
    symbol_list.extend(um_symbol_list)

    def inner_func(symbol):
        if '_PERP' in symbol:
            market_type = 'cm_futures'
        else:
            market_type = 'um_futures'
        file_name = os.path.join(file_path, f'{symbol}_funding_rate.csv')

        if os.path.exists(file_name):
            try:
                history_funding_rate = pd.read_csv(file_name, index_col='datetime')
                start_date = history_funding_rate.index[-1]
                if start_date[:10] == end_date:
                    logger.info(f'{symbol}资金费率数据已经最新')
                    all_data = history_funding_rate['funding_rate']
                    all_data.name = symbol
                    if market_type == 'cm_futures':
                        cm_data_df = all_data
                    else:
                        cm_data_df = None
                    if market_type == 'um_futures':
                        um_data_df = all_data
                    else:
                        um_data_df = None
                    return all_data, cm_data_df, um_data_df
            except Exception as e:
                logger.info(f"读取csv文件{file_name}报错：{e}")
                start_date = '2019-01-01 00:00:00'
                history_funding_rate = pd.DataFrame()

        else:
            start_date = '2019-01-01 00:00:00'
            history_funding_rate = pd.DataFrame()

        start = time.mktime(datetime.datetime(int(start_date[:4]), int(start_date[5:7]), int(start_date[8:10]), 0, 0, 0, tzinfo=tzutc()).timetuple())
        end = time.mktime(datetime.datetime(int(end_date[:4]), int(end_date[5:7]), int(end_date[-2:]), 23, 59, 59, tzinfo=tzutc()).timetuple())

        logger.info(f'开始获取{symbol}资金费率数据')
        data = fetch_binance_funding_rate(symbol, market_type, start, end, '8h')
        if data is None:
            logger.info(f"{symbol}数据为空")
            return None, None, None
        data['timestamp'] = data.apply(lambda x: int(x['timestamp'] / 1000), axis=1)
        data['date'] = pd.to_datetime(data['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert(timezone)
        data['date'] = data['date'].dt.strftime('%Y-%m-%d')
        data['datetime'] = pd.to_datetime(data['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert(timezone)
        data['datetime'] = data['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S')
        data['time'] = pd.to_datetime(data['timestamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert(timezone)
        data['time'] = data['time'].dt.strftime('%H:%M:%S')
        data.set_index('datetime', inplace=True)
        data.sort_index(inplace=True)

        all_data = pd.concat([history_funding_rate, data])
        all_data = all_data[~all_data.index.duplicated(keep='first')]
        all_data.to_csv(file_name)

        all_data = all_data['funding_rate']
        all_data.name = symbol
        if market_type == 'cm_futures':
            cm_data_df = all_data
        else:
            cm_data_df = None
        if market_type == 'um_futures':
            um_data_df = all_data
        else:
            um_data_df = None
        time.sleep(1)

        return all_data, cm_data_df, um_data_df

    result = Parallel(n_jobs=30, verbose=10)(delayed(inner_func)(param) for param in symbol_list)
    all_data_df_list, all_cm_data_df_list, all_um_data_df_list = zip(*result)
    all_data_df_list = [i for i in all_data_df_list if i is not None]
    all_cm_data_df_list = [i for i in all_cm_data_df_list if i is not None]
    all_um_data_df_list = [i for i in all_um_data_df_list if i is not None]
    all_funding_rate_df = pd.concat(all_data_df_list, axis=1)
    all_cm_funding_rate_df = pd.concat(all_cm_data_df_list, axis=1)
    all_um_funding_rate_df = pd.concat(all_um_data_df_list, axis=1)
    all_funding_rate_df.sort_index(inplace=True)
    all_cm_funding_rate_df.sort_index(inplace=True)
    all_um_funding_rate_df.sort_index(inplace=True)

    file_name = os.path.join(FUNDING_RATE_DATA_DIR, f'all_market_funding_rate.csv')
    all_funding_rate_df.to_csv(file_name)
    file_name = os.path.join(FUNDING_RATE_DATA_DIR, f'all_cm_funding_rate.csv')
    all_cm_funding_rate_df.to_csv(file_name)
    file_name = os.path.join(FUNDING_RATE_DATA_DIR, f'all_um_funding_rate.csv')
    all_um_funding_rate_df.to_csv(file_name)


if __name__ == '__main__':
    update_all_binance_funding_rate()
